package com.xiaobai.ThreadMessageQueue;

import com.xiaobai.util.ThreadUtil;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.util.LinkedList;

/*
线程中的消息队列
 */
@Slf4j
public class MessageQueueByThread {
    public static void main(String[] args) {
        MessageQueue messageQueue = new MessageQueue(2);
        for (int i = 0; i < 3; i++) {
            int id = i;
            new Thread(() -> {
                messageQueue.put(new Message(id, "消息" + id));
            }, String.valueOf(i)).start();
        }
        ThreadUtil.sleep(1);
        new Thread(() -> {
            while (true) {
                Message message = messageQueue.take();
                log.debug("消费消息{}", message);
                System.out.println();
            }
        }, "消费者").start();
    }
}

@Slf4j
class MessageQueue {
    private int capacity;
    private final LinkedList<Message> queue = new LinkedList<>();

    public MessageQueue(int capacity) {
        this.capacity = capacity;
    }

    public Message take() {
        synchronized (queue) {
            while (queue.isEmpty()) {
                try {
                    queue.wait();
                } catch (InterruptedException e) {
                    log.debug("线程中断异常{}", e.getMessage());
                }
            }
            Message message = queue.removeFirst();
            log.debug("取出消息{}", message);
            queue.notifyAll();
            return message;
        }
    }

    public void put(Message message) {
        synchronized (queue) {
            while (queue.size() >= capacity) {
                try {
                    log.debug("队列已满");
                    queue.wait();
                } catch (InterruptedException e) {
                    log.debug("线程中断异常{}", e.getMessage());
                }
            }
            log.debug("添加消息{}", message);
            queue.addLast(message);
            queue.notifyAll();
        }
    }
}

@Getter
class Message {
    private int id;
    private String msg;

    public Message(int id, String msg) {
        this.id = id;
        this.msg = msg;
    }

    @Override
    public String toString() {
        return "Message{" +
                "id=" + id +
                ", msg='" + msg + '\'' +
                '}';
    }
}